package gitobject;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;

import branch.Branch;
import fileoperation.FileReader;
import sha1.SHA1;
import repository.Repository;
import zlib.ZLibUtils;

public class Commit extends GitObject {
    protected String tree;        // the sha1 value of present committed tree
    protected String parent;    // the sha1 value of the parent commit
    protected String author;    // the author's name and timestamp
    protected String committer; // the committer's info
    protected String message;    // the commit memo
    protected String date;

    public String getParent() {
        return parent;
    }

    public String getTree() {
        return tree;
    }

    public String getAuthor() {
        return author;
    }

    public String getCommitter() {
        return committer;
    }

    public String getDate() {
        return date;
    }

    public String getMessage() {
        return message;
    }

    public Commit() {
    }

//    /**
//     * Construct a commit directly from a file.
//     *
//     * @param author, committer, message参数在git commit命令里创建
//     * @throws Exception
//     */
//    public Commit(String treePath, String author, String committer, String message, String date) throws Exception {
//        this.fmt = "commit";    //type of object
//        this.tree = new Tree(new File(treePath)).getKey();
//        this.parent = getLastCommit() == null ? "" : getLastCommit(); //null means there is no parent commit.
//        this.author = author;
//        this.committer = committer;
//        this.message = message;
//        this.date = date;
//        /*Content of this commit, like this:
//         *tree bd31831c26409eac7a79609592919e9dcd1a76f2
//         *parent d62cf8ef977082319d8d8a0cf5150dfa1573c2b7
//         *author xxx  1502331401 +0800
//         *committer xxx  1502331401 +0800
//         *修复增量bug
//         * */
//        this.value = "tree " + this.tree + "\nparent " + this.parent + "\nauthor " + this.author + "\ncommitter " + this.committer + " "+ this.date+"\n" + this.message;
//        key = genKey();
//        compressWrite();
//    }

    /**
     * Construct a commit from a built tree.
     *
     * @param author, committer, message参数在git commit命令里创建
     * @throws Exception
     */
    public Commit(Tree t, String author, String committer, String message, String date) throws Exception {
        this.fmt = "commit";    //type of object
        this.tree = t.getKey();
        this.parent = getLastCommit() == null ? null : getLastCommit(); //null means there is no parent commit.
        this.author = author;
        this.committer = committer;
        this.message = message;
        this.date = date;
        this.value = "tree " + this.tree +
                "\nparent " + this.parent +
                "\nauthor " + this.author +
                "\ncommitter " + this.committer +
                "\ndate " + this.date +
                "\nmessage " + this.message;
        key = genKey();
        compressWrite();
    }

    /**
     * Deserialize the commit object from its key(commitId)
     *
     * @param commitId
     * @throws IOException
     */
    public static Commit deserialize(String commitId) throws IOException {
        Commit result = new Commit();
        try {
            /**
             * Todo: Add your code here.
             */
            String filepath = path + File.separator + commitId;
            FileInputStream fis = new FileInputStream(filepath);
            byte[] dcp = ZLibUtils.decompress(fis);
            fis.close();
            ByteArrayInputStream bai = new ByteArrayInputStream(dcp);
            ObjectInputStream ois = new ObjectInputStream(bai);
            bai.close();
            result = (Commit) (ois.readObject());
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * Generate the hash value of this commit.
     *
     * @return key
     */
    public String genKey() throws Exception {
        key = SHA1.getHash(value);
        return key;
    }

    /**
     * Get the parent commit from the HEAD file.
     *
     * @return
     * @throws IOException
     */
    public static String getLastCommit() throws IOException {
        File HEAD = new File(Repository.getGitDir() + File.separator + "HEAD");

        String path = getValue(HEAD).substring(5).replace("\n", "");
        File branchFile = new File(Repository.getGitDir() + File.separator + path);

        if (branchFile.isFile()) {
            return getValue(branchFile);
        } else {
            return null;
        }
    }

    public void getLog() throws Exception {
        System.out.println("commit " + getKey() + " (HEAD -> " + Branch.getCurrentBranchName() + ")\r\n" +
                getValue() + "\r\n");
        String parentHash = parent;
        while (parentHash != null) {
            Commit c = deserialize(parentHash);
            System.out.println("commit " + c.getKey() + "\r\n" + c.getValue() + "\r\n");
            parentHash = c.parent;
        }
    }
}